<template>
  <BasicModal
    v-bind="$attrs"
    @register="registerArticleEditModal"
    :title="displayModuleTitle"
    :default-fullscreen="true"
  >
    <!-- <template #insertFooter>
      <a-button type="default" @click="saveAndFixedFormat">保存并固定格式</a-button>
    </template> -->
    <BasicForm @register="registerArticleEditForm">
      <!-- 针对文章内容单独使用slot方式，方便使用编辑器的属性和事件 -->
      <template #articleContentEditor="{ model, field }">
        <!-- <p>内容类型：{{ model.ctype }}</p> -->
        <!-- Tinymce中绑定model-value为只读，无法双向绑定，获取编辑的内容通过change获取 -->
        <Tinymce
          v-if="model.ctype === 1 || model.ctype === '1'"
          @change="onArticleContentEditorChange"
          @fileUploadSuccess="onTinymceFileUploadSuccess"
          :model-value="articleContent"
          :contentStyles="contentStyles"
          :height="600"
          ref="tinymceEdit"
        ></Tinymce>
        <!-- MarkDown中绑定model-value不确定是否为只读，但无法通过双向绑定获取数据，获取编辑的内容通过change获取 -->
        <MarkDown
          v-if="model.ctype === 2 || model.ctype === '2'"
          @change="onArticleContentEditorChange"
          :value="articleContent"
          :height="600"
        ></MarkDown>
        <!-- input直接使用v-model实现双向绑定，不需要在change事件中赋值；注意必须要写 v-model -->
        <a-input
          v-if="model.ctype === 3 || model.ctype === '3'"
          v-model:value="articleContent"
          placeholder="请输入外部链接地址"
        />
      </template>
      <!-- 从文章内容中的图片选择封面图片 -->
      <template #articleCoverImageSelect="{ model, field }">
        <a-space size="small">
          <template v-for="item in articleContentImages">
            <div>
              <a-image
                v-if="coverImageId == item.id"
                :width="100"
                :preview="false"
                :src="getImageFileUrlPrefix + item.id"
                @click="onSetArticleCoverClick(item.id)"
                style="border: 5px solid cornflowerblue"
              />
              <a-image
                v-if="coverImageId != item.id"
                :width="100"
                :preview="false"
                :src="getImageFileUrlPrefix + item.id"
                @click="onSetArticleCoverClick(item.id)"
              />
              <!-- <CheckCircleTwoTone /> -->
              <!-- <CheckSquareTwoTone v-if="coverImageId == item.id" /> -->
              <!-- <EyeInvisibleOutlined v-if="coverImageId != item.id" /> -->
            </div></template
          >
          <div>
            <Upload
              name="file"
              @change="onUploadCoverImageChange"
              :action="uploadFileUrl"
              :showUploadList="false"
              :accept="'.jpg,.jpeg,.gif,.png'"
              :max-count="1"
            >
              <a-button type="default" @click="onUploadCoverButtonClick"
                >选择图片上传作为文章封面</a-button
              >
            </Upload>
          </div></a-space
        >
      </template>
    </BasicForm>
    <template #footer>
      <a-button key="back" @click="onArticleEditModalCancelButtonClick">取消</a-button>
      <a-checkbox
        v-if="contentStyles && Object.keys(contentStyles).length > 0"
        v-model:checked="formatCheck"
        style="margin: 0 10px"
        >保存时格式化</a-checkbox
      >
      <a-button key="submit" type="primary" @click="onArticleEditModalOkButtonClick">确认</a-button>
    </template>
  </BasicModal>
</template>
<script lang="ts">
  import { defineComponent, ref, unref, computed, provide } from 'vue';
  import {
    CheckCircleTwoTone,
    CheckSquareTwoTone,
    EyeInvisibleOutlined,
  } from '@ant-design/icons-vue';
  import { Upload } from 'ant-design-vue';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { BasicForm, useForm } from '/@/components/Form/index';
  import { useComponentRegister } from '/@/components/Form/index';
  import { Tinymce } from '/@/components/Tinymce/index';
  import { MarkDown, MarkDownActionType } from '/@/components/Markdown';
  import { OperationTypeEnum } from '/@/enums/appEnum';
  import { QcUnifyTransToChildProps } from '/#/QcUnify';
  import { FILE_UPLOAD_PROPS_KEY } from '/@/enums/provideEnum';
  import { displayTitle, replaceAll } from '/@/utils/QcUnifyUtil';
  import { Tag } from 'ant-design-vue';

  import { useGlobSetting } from '/@/hooks/setting';
  import {
    FileInfo,
    getImageFileApi,
    getFileApi,
    uploadFileApi,
    uploadImageFileViewUrlPrefix,
    uploadVideoFileViewUrlPrefix,
  } from '/@/api/platform/file';

  import { articleEditFormSchema } from './articles.data';
  import { getArticle, saveArticle } from '/@/api/cms/article';
  import { useMessage } from '/@/hooks/web/useMessage';
  // const { createMessage, createErrorModal } = useMessage();
  const { createMessage } = useMessage();

  import { queryValidListSimple } from '/@/api/cms/category'; // api
  import { CategoryQueryConditionDto } from '/@/api/cms/model/categoryModel';
  import { getParamValues } from '/@/api/platform/paramValue';

  export default defineComponent({
    name: 'CmsArticleEdit',
    components: {
      CheckCircleTwoTone,
      CheckSquareTwoTone,
      EyeInvisibleOutlined,
      BasicModal,
      BasicForm,
      Tinymce,
      MarkDown,
      Upload,
      Tag,
    },
    emits: ['success', 'register'],
    setup(_, { emit }) {
      const qcUnifyProps = ref<QcUnifyTransToChildProps>();
      const articleId = ref('');
      const articleContent = ref<string | undefined>();
      const coverImageId = ref<string | number | undefined>();
      //使用provide和inject在文章编辑和文件上传组件中传递上传的图片文件信息
      provide(FILE_UPLOAD_PROPS_KEY, { accept: '.jpg,.jpeg,.gif,.png,.webp,.mp4', maxCount: 1 });
      //记录文章内容中已上传的图片
      const articleContentImages = ref<FileInfo[]>([]);

      const { uploadUrl } = useGlobSetting();
      const getImageFileUrlPrefix = ref<string>(uploadUrl + getImageFileApi);
      const getVideoFileUrlPrefix = ref<string>(uploadUrl + getFileApi);
      //文章封面图片的上传状态，是否正在上传
      let uploading = false;
      const uploadFileUrl = uploadUrl + uploadFileApi;

      const { globalProjectCode } = useGlobSetting();
      const projectCode = ref<String>(globalProjectCode);

      // cms文章内容样式
      const contentStyles = ref({});

      const tinymceEdit = ref(null);

      const formatCheck = ref(true);
      /**
       * 显示的模块标题，用于显示在弹出框中的标题
       */
      let displayModuleTitle = computed(() => {
        return displayTitle(qcUnifyProps.value);
      });

      const [
        registerArticleEditForm,
        { setFieldsValue, getFieldsValue, resetFields, validate, updateSchema },
      ] = useForm({
        labelWidth: 100,
        schemas: articleEditFormSchema,
        showActionButtonGroup: false,
        actionColOptions: {
          span: 23,
        },
      });

      const [registerArticleEditModal, { setModalProps, closeModal }] = useModalInner(
        async (data: QcUnifyTransToChildProps) => {
          //根据传递过来的参数获取对应的操作，操作不同所对应的界面不同
          //接收父组件传递的数据
          console.log('registerArticleEditModal data', data);
          if (data != undefined && data != null) {
            qcUnifyProps.value = unref(data);
            //从父组件中传递过来的文章ID，没有时赋值为undefined，有值时设置为修改的文章ID
            articleId.value = data.dataId;
          }

          resetFields();
          //清空原有的上传图片集合--供选择作为封面图片
          let emptyImages = [];
          articleContentImages.value = emptyImages;
          //自定义表单中Tinymce在使用form的resetFields方法后内容未能重置，在form定义中设置defaultValue可以解决该问题
          setModalProps({ confirmLoading: false });

          getCmsArticleStyles();

          //如果是修改数据，根据传入的id获取数据后进行赋值
          if (qcUnifyProps.value?.operateType == OperationTypeEnum.ADD) {
            //新增文章操作时设置文章内容为空，实测使用 = ''正常，使用= undefined无法清空原有内容
            articleContent.value = '';
            // articleContent.value = undefined;
            //设置后无效，起草文件保存后再起草内容未清空
            // setFieldsValue({
            //   content: ' ',
            // });
            //设置栏目下拉列表
            getAllValidCategories();
          }
          //如果是修改数据，根据传入的id获取数据后进行赋值
          else if (qcUnifyProps.value?.operateType == OperationTypeEnum.EDIT) {
            //设置栏目下拉列表
            getAllValidCategories();
            //获取文章信息
            getArticle({ id: articleId.value })
              .then((res) => {
                console.log('getArticle res', res);
                //对文章的内容进行赋值，以免出现未对内容进行修改直接点击保存时没有值的情况
                articleContent.value = res.content;
                //将文章内容中的图片和视频url前缀进行替换还原
                if (
                  articleContent.value != undefined &&
                  articleContent.value != null &&
                  articleContent.value.length > 0x0
                ) {
                  articleContent.value = replaceAll(
                    articleContent.value,
                    uploadImageFileViewUrlPrefix + getImageFileApi,
                    getImageFileUrlPrefix.value,
                  );
                  articleContent.value = replaceAll(
                    articleContent.value,
                    uploadVideoFileViewUrlPrefix + getFileApi,
                    getVideoFileUrlPrefix.value,
                  );
                }
                //判断是否存在封面图片ID，如果存在先将封面图片ID显示在封面图片选择列表中
                coverImageId.value = undefined;
                if (res.cover != undefined && res.cover != null && res.cover > 0) {
                  coverImageId.value = res.cover;
                  articleContentImages.value.push({
                    name: coverImageId.value,
                    id: coverImageId.value,
                    type: 'image',
                  });
                }
                //设置封面图片，处理后的封面图片在后台返回图片ID为0时显示为空，避免显示错误
                res.cover = coverImageId.value;
                //根据文章内容类型和文章内容，在内容类型为富文本-1时对文章内容中的图片进行解析赋值
                if (res.ctype === 1 || res.ctype === '1') {
                  if (res.content != undefined && res.content != null && res.content.length > 0x0) {
                    const contentHtml = new DOMParser().parseFromString(res.content, 'text/html');
                    //按TagName为img获取元素
                    let images = contentHtml.body.getElementsByTagName('img');
                    if (images != undefined && images != null && images.length > 0x0) {
                      for (let i = 0; i < images.length; i++) {
                        const imageElement = images[i];
                        //获取img的src属性值
                        const imageSrc = imageElement.getAttribute('src');
                        //判断图片是否为本地上传图片，根据获取图片的路径进行判断
                        if (imageSrc.indexOf(getImageFileApi) >= 0x0) {
                          let imageIdStartIndex = imageSrc.lastIndexOf('/');
                          if (imageIdStartIndex > 0x0) {
                            let imageId = imageSrc.substring(imageIdStartIndex + 1);
                            //判断如果图片ID与封面图片ID相同时不进行重复显示
                            if (coverImageId.value != undefined && coverImageId.value != null) {
                              if (coverImageId.value != imageId) {
                                articleContentImages.value.push({
                                  name: imageId,
                                  id: imageId,
                                  type: 'image',
                                });
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
                //将附件的字符串json对象化
                let attachmentJson = [];
                if (!!res && !!res.attachment) {
                  attachmentJson = JSON.parse(res.attachment);
                }
                res.attachment = attachmentJson;
                //设置表单数据
                setFieldsValue({
                  ...res,
                });
              })
              .catch((ex) => {
                console.log('catch ', ex);
                createMessage.error(ex.msg);
              });
          }
        },
      );

      /**
       * Tinymce中上传图片成功事件，用于获取上传的图片信息以便于在此界面中选择作为封面图片
       * @param data
       */
      async function onTinymceFileUploadSuccess(data) {
        console.log('onTinymceFileUploadSuccess data', data);
        articleContentImages.value.push({
          name: data.name,
          id: data.fileid,
          type: data.type,
        });
        //判断如果当前没有设置封面图片，默认使用第1张作为封面图片
        let fieldsValue = await getFieldsValue();
        if (fieldsValue != undefined && fieldsValue != null) {
          if (
            fieldsValue.cover == undefined ||
            fieldsValue.cover == null ||
            fieldsValue.cover == '' ||
            fieldsValue.cover == 0 ||
            fieldsValue.cover == '0'
          ) {
            onSetArticleCoverClick(data.fileid);
          }
        }
      }

      /**
       * 文章内容编辑器中内容变化时的事件，获取编辑器中的值进行赋值
       * @param data
       */
      async function onArticleContentEditorChange(data) {
        console.log('onArticleContentEditorChange data', data);
        articleContent.value = data;
      }

      async function getCmsArticleStyles() {
        getParamValues({
          tablecode: 'qc_project',
          objectids: projectCode.value,
          paramnodes: 'cmsArticleStyles>*',
        })
          .then((res) => {
            console.log('getParamValue res', res);
            if (!res || Object.keys(res).length > 0x0) {
              for (let i = 0; i < res.length; i++) {
                let values = res[i].values;
                if (!values || Object.keys(values).length > 0x0) {
                  contentStyles.value = res[i].values;
                }
              }
            }
          })
          .catch((ex) => {
            console.log('catch ', ex);
            // createMessage.error(ex.msg);
          });
      }

      /**
       * 点击图片设置为文章封面图片ID
       * @param fileid
       */
      async function onSetArticleCoverClick(fileid) {
        console.log('onSetArticleCoverClick data', fileid);
        coverImageId.value = fileid;
        setFieldsValue({
          cover: fileid,
        });
      }

      /**
       * 点击上传文章封面图片按钮
       * @param fileid
       */
      async function onUploadCoverButtonClick(fileid) {
        console.log('onUploadCoverButtonClick data', fileid);
      }

      /**
       * 文章封面图片上传处理事件
       * @param info
       */
      async function onUploadCoverImageChange(info: Recordable) {
        // console.log('onUploadCoverImageChange info', info);
        const file = info.file;
        const status = file?.status;
        //渠成上传文件接口后台没有返回url，获取返回的文件id
        // const url = file?.response?.url;
        const fileid = file?.response?.data?.fileid;
        const name = file?.name;
        const type = file?.type;

        if (status === 'uploading') {
          if (!uploading) {
            uploading = true;
          }
        } else if (status === 'done') {
          //还需要根据渠成上传文件后台反馈的状态和信息进行判断
          if (!file.response) {
            //后台接口响应信息为空
            createMessage.error('文件上传失败，后台无处理响应结果。');
            uploading = false;
          } else {
            if (file.response.code === 0) {
              //如果msg为空表示正确，msg不为空表示错误提示信息
              if (!file.response.msg) {
                //判断data中的结果，根据data中的success判断是否成功
                if (!file.response.data) {
                  createMessage.error('文件上传失败，后台响应结果中无任何数据。');
                  uploading = false;
                } else {
                  if (file.response.data.success === true) {
                    //文件上传成功，在图片集合中添加信息，并设置封面图片ID
                    articleContentImages.value.push({
                      name: name,
                      id: fileid,
                      type: type,
                    });
                    onSetArticleCoverClick(fileid);

                    uploading = false;
                  } else {
                    createMessage.error(file.response.data.msg);
                    uploading = false;
                  }
                }
              } else {
                createMessage.error(file.response.msg);
                uploading = false;
              }
            } else {
              //code不为0表示错误
              createMessage.error(
                '文件上传失败，后台处理代码为：' +
                  file.response.code +
                  '，后台提示信息为：' +
                  file.response.msg,
              );
              uploading = false;
            }
          }
        } else if (status === 'error') {
          //根据file.response信息判断错误提示
          let errorMessageContent = '文件上传失败';
          if (info.file.response.code === 0) {
            //请求完成，返回错误提示信息
            errorMessageContent = '文件上传失败，' + file?.response?.data.data.msg;
          } else {
            //请求错误
            errorMessageContent = '文件上传失败，' + file?.response?.error;
          }
          createMessage.error(errorMessageContent);
          uploading = false;
        }
      }

      /**
       * 获取所有有效的栏目集合，用于新增或修改文章时进行选择
       */
      function getAllValidCategories() {
        //显示的栏目信息只包含有效状态，并且根据用户所在部门进行过滤
        let queryConditionDto: CategoryQueryConditionDto = {
          isall: false,
          isdept: true,
          isvisible: true,
        };
        queryValidListSimple(queryConditionDto)
          .then((res) => {
            console.log('getAllValidCategories res', res);
            let categoryOptions = [];
            res.forEach((category) => {
              //options的value类型必须与表单中对应字段的类型一致，否则无法自动选中
              let categoryId: number = category.id as number;
              //根据层级在栏目名称前添加空格，实测空格无效，显示时没有空格
              let prefixSpaces = '';
              for (let index = 0; index < category.level; index++) {
                prefixSpaces += '----';
              }
              // 注意：栏目是否允许发文属性candraft默认为true表示允许发文，
              // 但是下拉选择项是否禁用默认为false，所以下方禁用的栏目是disabled为true，而candraft为false时，取反。
              categoryOptions.push({
                value: categoryId,
                label: prefixSpaces + category.name,
                disabled: !category.candraft,
              });
            });

            updateSchema({
              field: 'cid',
              componentProps: {
                options: categoryOptions,
              },
            });
          })
          .catch((ex) => {
            console.log('catch ', ex);
            createMessage.error(ex.msg);
          });
      }

      /**
       * 保存文章事件
       */
      async function onArticleEditModalOkButtonClick() {
        const values = await validate();
        console.log('values', values);

        if (values.ctype == 1 || values.ctype == '1') {
          //调用Tinymce中的设置文章内容固定格式的方法
          // 如果用户选择了保存时格式化且存在格式化格式,才进行格式化操作
          if (
            formatCheck.value &&
            contentStyles.value &&
            Object.keys(contentStyles.value).length > 0
          ) {
            await tinymceEdit.value.setCmsAarticleFormat();
            console.log('进行了格式化操作');
          }
        }
        //根据指定的操作类型分别进行提交数据和处理
        if (
          qcUnifyProps.value?.operateType == OperationTypeEnum.ADD ||
          qcUnifyProps.value?.operateType == OperationTypeEnum.EDIT
        ) {
          //对应操作的步骤为：验证表单、提交后台保存、关闭modal、调用父组件事件刷新数据
          try {
            console.log('onArticleEditModalOkButtonClick articleContent ', articleContent.value);

            setModalProps({ confirmLoading: true });
            console.log('articleContent ===', articleContent.value);
            //由于单独使用编辑器进行文章内容编辑，需要手动进行赋值
            values.content = articleContent.value;
            //替换文章内容中的图片和视频url前缀，方便后面查询出来时再替换回去
            if (
              articleContent.value != undefined &&
              articleContent.value != null &&
              articleContent.value.length > 0x0
            ) {
              values.content = replaceAll(
                values.content,
                getImageFileUrlPrefix.value,
                uploadImageFileViewUrlPrefix + getImageFileApi,
              );
              values.content = replaceAll(
                values.content,
                getVideoFileUrlPrefix.value,
                uploadVideoFileViewUrlPrefix + getFileApi,
              );
            }

            //验证过后的表单数据对其中的文件ID集合信息进行修改
            console.log('onArticleEditModalOkButtonClick validate values', values);
            let fileIds = '';
            if (values.attachment && values.attachment.length > 0x0) {
              //将json对象转换为字符串
              fileIds = JSON.stringify(values.attachment);
              //   values.files.forEach((element) => {
              //     fileIds += element.id + ',';
              //   });
            }
            values.attachment = fileIds;

            //调用接口进行保存
            //判断是否有自动发布到首页轮播图
            // if (values.autToSwipper === 1 || values.autToSwipper === '1') {
            //   //对提交数据中的属性进行赋值，界面中未进行显示和输入，后继可以修改为由人工在界面中进行选择输入
            //   //固定设置发布轮播图到首页栏目
            //   values.swipperCid = 1;
            // }
            saveArticle(values)
              .then((res) => {
                if (!res || Object.keys(res).length == 0) {
                  createMessage.success('文章保存成功。', 2);
                }
                closeModal();
                emit('success');
              })
              .catch((ex) => {
                console.log('catch ', ex);
                createMessage.error(ex.msg);
              });
          } finally {
            setModalProps({ confirmLoading: false });
          }
        } else {
          createMessage.error('当前操作类型错误，无法进行对应操作。', 5);
        }
      }

      /**
       * 文章编辑Modal点击取消/关闭事件
       */
      async function onArticleEditModalCancelButtonClick() {
        //清空文章内容
        articleContent.value = '';
        closeModal();
      }

      /**
       * 文章内容类型选择变化时处理事件，更换界面中的文章内容输入框（富文本编辑器、MarkDown编辑器、Input输入外部链接）
       * @param value 文章内容类型，富文本-1、Markdown-2，外部链接-3
       */
      async function handleFormCtypeChange(value) {
        console.log('handleFormCtypeChange', value);
        // //如果有传入参数使用传入参数，没有传入参数使用从表单中获取的数据值
        // if (typeof value === 'object') {
        //   const values = await getFieldsValue();
        //   value = values.ctype;
        // }
        // if (value === 1 || value === '1') {
        //   //富文本，使用tinymce编辑
        //   useComponentRegister('Tinymce', Tinymce);
        //   updateSchema({
        //     field: 'content',
        //     component: 'Tinymce',
        //     show: true,
        //   });
        // } else if (value === 2 || value === '2') {
        //   //  MarkDown
        //   useComponentRegister('MarkDown', MarkDown);
        //   updateSchema({
        //     field: 'content',
        //     component: 'MarkDown',
        //     show: true,
        //   });
        // } else if (value === 3 || value === '3') {
        //   //  外部链接
        //   updateSchema({
        //     field: 'content',
        //     component: 'Input',
        //     show: true,
        //   });
        // }
      }

      return {
        displayModuleTitle,
        articleContent,
        coverImageId,
        articleContentImages,
        getImageFileUrlPrefix,
        getVideoFileUrlPrefix,
        uploadFileUrl,
        handleFormCtypeChange,
        registerArticleEditModal,
        registerArticleEditForm,
        getAllValidCategories,
        onArticleContentEditorChange,
        onTinymceFileUploadSuccess,
        onSetArticleCoverClick,
        onUploadCoverButtonClick,
        onUploadCoverImageChange,
        onArticleEditModalOkButtonClick,
        onArticleEditModalCancelButtonClick,
        contentStyles,
        tinymceEdit,
        formatCheck,
      };
    },
  });
</script>
<style scoped lang="less"></style>
